(ns cljsso.core
  (:gen-class)
  (:require
   [taoensso.timbre :as timbre]
   [taoensso.timbre.appenders.rolling :refer [make-rolling-appender]]
   [noir.util.middleware :as noir-middleware]
   [ring.middleware.defaults :refer [site-defaults]]
   [noir.session :as session]
   [org.httpkit.server :refer [run-server]]
   [ring.middleware.reload :as reload]

   [sparrows.misc :refer [trim]]
   [cljsso.config :refer [props]]
   [cljsso.routes :refer [app-routes main-routes base-routes]]
   [cljsso.logger :refer [wrap-request-logger]]
   [cljsso.store :refer [check-ticket gen-ticket invalidate-ticket
                         get-userinfo-from-ticket
                          init-host-keys]]

   [clojure.tools.nrepl.server :refer [start-server stop-server]]))



(defn- rolling-appender
  []
  (make-rolling-appender
   {:enabled? true}
   {:path (:log-file props)
    :pattern :daily}))

(defn- init-timbre
  []
  (timbre/set-config! [:timestamp-pattern] "yyyy-MMM-dd HH:mm:ss.SSS ZZ")
  (timbre/set-config! [:appenders :spit :enabled?] true)
  (timbre/set-config! [:shared-appender-config :spit-filename] (:log-file props))
  (timbre/set-config! [:appenders :spit :min-level] (:log-level props))

  (timbre/set-config! [:appenders :rolling] (rolling-appender)))

(defonce repl-server
  (atom nil))

(defonce repl-port
  (:nrepl-port props))


(defn- init-repl
  []
  (reset! repl-server (start-server :port repl-port)))


(defn init []
  (timbre/info "Server is starting ...")
  (init-timbre)
  (timbre/info "Registered sso clients:" (:sso-clients props))

  (when repl-port
    (timbre/info "Starting live repl server ...")
    (init-repl)
    (timbre/info "Repl server started, port number" repl-port)))



(defn user-page
  [{cookies :cookies}]
  (timbre/debug "Checking ticket:" (get-in cookies ["ticket" :value]))
  (when-let [ticket (trim (get-in cookies ["ticket" :value]))]
    (when (check-ticket  ticket)
      (when-not (session/get :ticket)
        (session/put! :ticket ticket)
        (session/put! :userinfo (get-userinfo-from-ticket ticket)))
      true)))

(def app
  (->
   (noir-middleware/app-handler
    [app-routes
     main-routes
     base-routes]
    :middleware [wrap-request-logger]
    ;; Uncomment to diable anti-forgery
;;    :ring-defaults (assoc-in site-defaults [:security :anti-forgery] false)
    :access-rules [{:rule user-page
                    :redirect "/login"}])))


(defn start-web
  [& [dev?]]
  (timbre/info "Starting web server ...")
  (let [options
        {:port (or (:port props) 3030)
         :max-body 83886080}]
    (if dev?
      (run-server (reload/wrap-reload app {:dirs ["src" "resources"]}) options)
      (run-server app options))))


(defn -main [& [dev?]]
  (init)
  (start-web dev?))
